package com.hfb.mashibing.alip8.juc.c020;



import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * reentrantLock 用于代替 synchronized
 * 由于m锁定this ，只有m执行完毕的时候，n才能执行
 * 这里是复习 synchronized 最原始的语义
 *
 * reentrantLock 可以完成同样的功能
 * 需要注意的是，必须要手动释放锁
 * 使用 synchronized 锁定的话，如遇异常jvm 会自动释放锁，
 * 但是lock必须手动释放，因此经常放在finally里
 *
 * 使用 reentrantLock 可以进行"尝试锁定"tryLock，
 * 这样(在规定时间内)无法锁定，代码都将继续执行
 *
 * 使用 ReentrantLock 还可以调用 lockInterruptibly 方法，
 * 可以对线程 Interruptibly ，在一个线程等等锁的过程中可以被打断。
 */

public class T04_ReentrantLock4 {

    public static void main(String[] args) {
        Lock lock = new ReentrantLock();

        Thread t1 = new Thread(() -> {
            try {
                lock.lock();
                System.out.println("t1 start");
                // 永远休眠
                TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
                System.out.println("t1 end");
            } catch (InterruptedException e) {
                System.out.println("InterruptedException!");
            } finally {
                lock.unlock();
            }
        }, "t1");
        t1.start();

        Thread t2 = new Thread(() -> {
            try {
                // 可以被打断的加锁
                lock.lockInterruptibly();// 可以对 Interrupt()方法做出响应
                System.out.println("t2 start");
                TimeUnit.SECONDS.sleep(5);

                System.out.println("t2 end");
            } catch (InterruptedException e) {
                System.out.println("InterruptedException!");
            } finally {
                lock.unlock();
            }
        }, "t2");
        t2.start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("打断线程t2的等待。。。");
        t2.interrupt();

    }

}
